package com.easy.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easy.common.exception.CustomException;
import com.easy.user.mapper.FavoriteMapper;
import com.easy.user.pojo.OrdFavorite;
import com.easy.user.service.IFavoriteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import static com.easy.common.utils.RedisConstants.FAVORITE_KEY;
import static com.easy.common.utils.RedisConstants.HOUSE_CONTRACTION_KEY;

@Service
public class FavoriteServiceImpl extends ServiceImpl<FavoriteMapper, OrdFavorite> implements IFavoriteService {
    @Autowired
    private FavoriteMapper favoriteMapper;


    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Resource(name = "redisTemplateHouse")
    private RedisTemplate<String, Object> redisTemplate;
    /**
     * 判断是否收藏
     *
     * @param rid 房屋对象id
     * @param uid 所属用户id
     * @return boolean 如果有值（true）代表收藏过了,反之（false）
     */
    @Override
    public boolean isFavorite(Long rid, Long uid) {
        Double score = stringRedisTemplate.opsForZSet().score(FAVORITE_KEY + uid, rid + "");
        if (score == null) {
            LambdaQueryWrapper<OrdFavorite> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrdFavorite::getRid, rid);
            wrapper.eq(OrdFavorite::getUid, uid);
            OrdFavorite ordFavorite = favoriteMapper.selectOne(wrapper);
            if (ordFavorite != null) {
                score = 0d;
            }
        }
        return score != null;
    }

    /**
     * 添加收藏
     *
     * @param rid   房屋对象id
     * @param uid   所属用户id
     * @param title 标题
     */
    @Override
    public void addFavorite(Long rid, Long uid, String title) {
        OrdFavorite ordFavorite = new OrdFavorite();
        ordFavorite.setRid(rid);
        ordFavorite.setDate(LocalDateTime.now());
        ordFavorite.setUid(uid);
        ordFavorite.setTitle(title);

        long time = System.currentTimeMillis();
        double score = 9999999999999d - time;
        try {
            // 添加收藏
            favoriteMapper.insert(ordFavorite);
            stringRedisTemplate.opsForZSet().add(FAVORITE_KEY + uid, rid + "", score);
        } catch (CustomException e) {
            throw new CustomException("房屋信息不存在");
        }
    }

    /**
     * 取消收藏
     *
     * @param rid 房屋对象id
     * @param uid 所属用户id
     */
    @Override
    public void delFavorite(Long rid, Long uid) {
        LambdaQueryWrapper<OrdFavorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrdFavorite::getRid, rid);
        wrapper.eq(OrdFavorite::getUid, uid);

        try {
            favoriteMapper.delete(wrapper);
            stringRedisTemplate.opsForZSet().remove(FAVORITE_KEY + uid, rid + "");
        } catch (CustomException e) {
            throw new CustomException("已删除");
        }
    }



    /**
     * 把最喜欢列表
     * 获取收藏列表
     *
     * @param page     当前页面
     * @param pageSize 页面数量
     * @param uid      uid
     * @param title    筛选值非必需
     * @return {@link Page}<{@link OrdFavorite}>
     */
    @Override
    public JSONObject getFavoriteList(int page, int pageSize, Long uid, String title) {
        //获取总条数
        long total = 0;
        try {
            total = stringRedisTemplate.opsForZSet().zCard(FAVORITE_KEY + uid);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //总页数
        long pages = total % pageSize == 0 ? total / pageSize : (total / pageSize + 1);
        //获取最大分值
        double maxScore = maxScore(FAVORITE_KEY + uid);
        //获取zset的区间
        Set<String> zSetValue = stringRedisTemplate.opsForZSet().rangeByScore(FAVORITE_KEY + uid, 0, maxScore, (page - 1) * pageSize, pageSize);
//        Set<String> zSetValue2 = stringRedisTemplate.opsForZSet().rangeByScore(FAVORITE_KEY + uid, 0, maxScore);


        JSONObject jsonObject = new JSONObject();
        List<HashMap<String, Object>> arr = new ArrayList<>();
        if (zSetValue != null) {
            flag:
            for (String s : zSetValue) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("id", s);
                Set<Object> keys = redisTemplate.opsForHash().keys(HOUSE_CONTRACTION_KEY + s);
                for (Object key : keys) {
                    Object value = redisTemplate.opsForHash().get(HOUSE_CONTRACTION_KEY + s, key);
                    map.put((String) key, value);
                    if (key.equals("title") && title != null) {
                        if (!((String) value).contains(title)) {
                            break flag;
                        }
                    }
                }
                arr.add(map);
            }
        }

        jsonObject.put("total", Math.toIntExact(total));//总条数
        jsonObject.put("size", pageSize);//页面数量
        jsonObject.put("current", page);//当前页
        jsonObject.put("pages", pages);//总页数
        jsonObject.put("records", arr);//数据
        return jsonObject;
    }

    public Double maxScore(String name) {
        Set<String> sortId = stringRedisTemplate.opsForZSet().reverseRange(name, 0, 0);
        if (sortId.size() == 0) {
            return 0d;
        } else {
            String hkey = String.valueOf(sortId.iterator().next());
            //根据member获得最大分值
            Double maxScore = stringRedisTemplate.opsForZSet().score(name, hkey);
            return maxScore;
        }

    }
}
